package com.cs307.redcross.client;

import java.io.Serializable;
import java.util.Vector;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.user.client.ui.TextArea;

public class UserGroupsContent extends Content implements Serializable {
	private static final long serialVersionUID = -1189011235559691201L;
	private DatabaseHandlerServiceAsync databaseHandlerService = (DatabaseHandlerServiceAsync) GWT.create(DatabaseHandlerService.class);
	private final String relogString = "If this problem persists try relogging into the system.";
	
	Vector<Group> groupVector = new Vector<Group>();
	Vector<Group> myGroupVector = new Vector<Group>();
	
	Group cancelGroup;
	Group selectedGroup;
	Group mySelectedGroup;
	Group groupCopy;
	Boolean callbackReceived;
	
	// UI Widgets
	ListBox groupListbox;
	TextBox groupNameTextbox;
	Button addGroupButton;
	PopupPanel popup;
	AddPersonPopupPanel appp;
	LoadingPopupPanel lpp = new LoadingPopupPanel();
	TextArea descriptionTextArea;
	private ListBox myGroupListbox;
	private Label lblGroupsImIn;
	private Button button;
	
	public UserGroupsContent() {	
		lpp.setAutoHideEnabled(false);
		lpp.setModal(true);
		
		ContentPanel.getInstance().showLoading(1, 80, 350);
		databaseHandlerService.getAllGroups(new AsyncCallback<Vector<Group>>() {
			
			@Override
			public void onSuccess(Vector<Group> result) {
				if (result != null && !result.isEmpty()) {
					for (Group group : result) {
						if (group == null)
							continue;
						
						boolean myGroup = false;
						if (group.getPersonList() != null && !group.getPersonList().isEmpty()) {
							for (Person person : group.getPersonList()) {
								if (person == null)
									continue;
								
								if (person.getID() == Server.currentUser.ID) {
									myGroup = true;
									break;
								}
							}
						}						                                            
						
						if (myGroup) {
							myGroupVector.add(group);
							myGroupListbox.addItem(group.getName());
						}
						else {
							if (!group.isPublic())
								continue;								
								
							groupVector.add(group);
							groupListbox.addItem(group.getName());
						}
					}
				}
				ContentPanel.getInstance().hideLoadingPopup(1);
			}
			
			@Override
			public void onFailure(Throwable caught) {
				ContentPanel.getInstance().hideLoadingPopup(1);
				Window.alert("Error: Failed to contact server. " + relogString);
				return;
			}
		});
		
		AbsolutePanel absolutePanel = new AbsolutePanel();
		initWidget(absolutePanel);
		absolutePanel.setSize("879px", "647px");
		
		Label lblSelectEvent = new Label("Available Groups:");
		absolutePanel.add(lblSelectEvent, 10, 209);
		
		Label lblEventName = new Label("Group Name:");
		absolutePanel.add(lblEventName, 307, 10);
		lblEventName.setSize("79px", "18px");
		
		groupNameTextbox = new TextBox();
		absolutePanel.add(groupNameTextbox, 307, 34);
		groupNameTextbox.setSize("331px", "13px");
		
		addGroupButton = new Button("Add");
		addGroupButton.setText("Add Me To Group");
		addGroupButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if (selectedGroup == null)
					return;
				
				popup = new PopupPanel();
				popup.setPopupPosition(100, 400);
				VerticalPanel vp = new VerticalPanel();
				vp.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
				vp.add(new Label("Are you sure you want to add yourself to " + selectedGroup.getName() + "?"));
				
				Button yesButton = new Button("Yes");
				yesButton.addClickHandler(new ClickHandler() {
					
					@Override
					public void onClick(ClickEvent event) {
						popup.hide();
						popup.clear();
						
						selectedGroup.addPersonToGroup(Server.currentUser);
						
						databaseHandlerService.write(selectedGroup, new AsyncCallback<Integer>() {

							@Override
							public void onFailure(Throwable caught) {
								Window.alert(("Error: failure to add you to the group. " + relogString));
							}

							@Override
							public void onSuccess(Integer result) {
								Window.alert("You were successfully added to the Group.");
								myGroupListbox.addItem(selectedGroup.getName());
								myGroupVector.add(selectedGroup);
								groupVector.remove(groupListbox.getSelectedIndex());
								groupListbox.removeItem(groupListbox.getSelectedIndex());
								groupListbox.setSelectedIndex(-1);
								clearForm();
								addGroupButton.setVisible(false);
							}
						});
					}
				});
				
				Button noButton = new Button("No");
				noButton.addClickHandler(new ClickHandler() {
					
					@Override
					public void onClick(ClickEvent event) {
						popup.hide();
						popup.clear();
					}
				});
				
				SimplePanel sp = new SimplePanel();
				sp.setSize("5px", "20px");
				
				HorizontalPanel hp = new HorizontalPanel();
				hp.add(yesButton);
				hp.add(new Label("         "));
				hp.add(noButton);
				
				vp.add(sp);
				vp.add(hp);
				popup.add(vp);
				popup.show();
			}
		});
		absolutePanel.add(addGroupButton, 10, 604);
		addGroupButton.setSize("158px", "24px");
		
		groupListbox = new ListBox();
		groupListbox.addChangeHandler(new ChangeHandler() {
			public void onChange(ChangeEvent event) {
				if (groupListbox.getSelectedIndex() != -1) {
					selectedGroup = groupVector.get(groupListbox.getSelectedIndex());
					
					if (selectedGroup != null) {
						populateForm();
						mySelectedGroup = null;
						myGroupListbox.setSelectedIndex(-1);
						addGroupButton.setVisible(true);
						button.setVisible(false);
					}
				}
			}
		});
		groupListbox.setVisibleItemCount(20);
		absolutePanel.add(groupListbox, 10, 233);
		groupListbox.setSize("259px", "365px");
		
		Label lblDescription = new Label("Description:");
		absolutePanel.add(lblDescription, 307, 78);
		
		descriptionTextArea = new TextArea();
		absolutePanel.add(descriptionTextArea, 307, 102);
		descriptionTextArea.setSize("501px", "490px");
		
		myGroupListbox = new ListBox();
		myGroupListbox.addChangeHandler(new ChangeHandler() {
			public void onChange(ChangeEvent event) {
				if (myGroupListbox.getSelectedIndex() != -1) {
					mySelectedGroup = myGroupVector.get(myGroupListbox.getSelectedIndex());
					
					if (mySelectedGroup != null) {
						populateForm();
						selectedGroup = null;
						groupListbox.setSelectedIndex(-1);
						addGroupButton.setVisible(false);
						button.setVisible(true);
					}
				}
			}
		});
		myGroupListbox.setVisibleItemCount(20);
		absolutePanel.add(myGroupListbox, 10, 34);
		myGroupListbox.setSize("259px", "99px");
		
		lblGroupsImIn = new Label("Groups I'm In:");
		absolutePanel.add(lblGroupsImIn, 10, 10);
		lblGroupsImIn.setSize("103px", "18px");
		
		button = new Button("Add");
		button.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if (mySelectedGroup == null)
					return;
				
				popup = new PopupPanel();
				popup.setPopupPosition(100, 400);
				VerticalPanel vp = new VerticalPanel();
				vp.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
				String warning = "";
				
				if (!mySelectedGroup.isPublic())
					warning = "Are you sure you want to remove yourself from " + mySelectedGroup.getName() + "?" + "\n\nThis is a private group so you will only be able to rejoin if an Admin adds you back into the group.";
				else
					warning = "Are you sure you want to remove yourself from " + mySelectedGroup.getName() + "?";
				
				vp.add(new Label(warning));
				
				Button yesButton = new Button("Yes");
				yesButton.addClickHandler(new ClickHandler() {
					
					@Override
					public void onClick(ClickEvent event) {
						popup.hide();
						popup.clear();
						
						mySelectedGroup.removePersonFromGroup(Server.currentUser);
						
						databaseHandlerService.write(mySelectedGroup, new AsyncCallback<Integer>() {

							@Override
							public void onFailure(Throwable caught) {
								Window.alert(("Error: failure to remove yourself from the group. " + relogString));
							}

							@Override
							public void onSuccess(Integer result) {
								Window.alert("You were successfully removed from the Group.");
								if (mySelectedGroup.isPublic()) {
									groupListbox.addItem(mySelectedGroup.getName());
									groupVector.add(mySelectedGroup);
								}
								
								myGroupVector.remove(myGroupListbox.getSelectedIndex());
								myGroupListbox.removeItem(myGroupListbox.getSelectedIndex());
								myGroupListbox.setSelectedIndex(-1);
								clearForm();
								button.setVisible(false);
							}
						});
					}
				});
				
				Button noButton = new Button("No");
				noButton.addClickHandler(new ClickHandler() {
					
					@Override
					public void onClick(ClickEvent event) {
						popup.hide();
						popup.clear();
					}
				});
				
				SimplePanel sp = new SimplePanel();
				sp.setSize("5px", "20px");
				
				HorizontalPanel hp = new HorizontalPanel();
				hp.add(yesButton);
				hp.add(new Label("         "));
				hp.add(noButton);
				
				vp.add(sp);
				vp.add(hp);
				popup.add(vp);
				popup.show();
			}
		});
		button.setText("Remove Me From Group");
		absolutePanel.add(button, 10, 139);
		button.setSize("197px", "24px");
		
		disableForm();
	}
		
	// populate form ************************************************************************
	private void populateForm() {
		clearForm();
		
		if (selectedGroup != null) {
			descriptionTextArea.setText(selectedGroup.getDescription());
			groupNameTextbox.setText(selectedGroup.getName());
			addGroupButton.setVisible(true);
			button.setVisible(false);
		}
		else if (mySelectedGroup != null) {
			descriptionTextArea.setText(mySelectedGroup.getDescription());
			groupNameTextbox.setText(mySelectedGroup.getName());
			addGroupButton.setVisible(false);
			button.setVisible(true);
		}			                                  
	}
	
	private void disableForm() {
		groupNameTextbox.setEnabled(false);
		descriptionTextArea.setEnabled(false);
		addGroupButton.setVisible(false);
		button.setVisible(false);
	}
	
	private void clearForm() {
		groupNameTextbox.setText("");
		descriptionTextArea.setText("");
	}
}
